home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
c
/
tagsgen.exe
/
ARGLIST.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-25
|
10KB
|
344 lines
/*
EPSHeader
File: arglist.c
Author: J. Kercheval
Created: Thu, 09/05/1991 20:01:35
*/
/*
EPSRevision History
J. Kercheval Thu, 09/05/1991 20:09:36 creation
J. Kercheval Thu, 09/05/1991 21:51:00 add DestroyArgList()
J. Kercheval Tue, 09/10/1991 23:51:03 add calls to external_cleanup() before exit(1)
J. Kercheval Wed, 09/11/1991 00:23:32 add ArgCopy()
J. Kercheval Wed, 09/18/1991 21:14:24 fix realloc bug in ArgRegisterArg
J. Kercheval Wed, 09/25/1991 14:05:13 add support for sorted argument lists
J. Kercheval Wed, 09/25/1991 16:47:35 fix bug in ArgList memory reallocation
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "arglist.h"
#include "log.h"
#define FILE_LIST_BLOCK_SIZE 2048 /* allocation block size */
/* the cleanup routine for problem exiting */
extern void external_cleanup(void);
/*----------------------------------------------------------------------------
*
* CreateArgList() will allocate the memory needed for the use of an ArgList
* variable and will set the initial values of the list. If sorted_list is
* TRUE then the list is maintained in sorted order when additions are made
* through the register arg routines.
*
---------------------------------------------------------------------------*/
ArgList CreateArgList(BOOLEAN sorted_list)
{
ArgList arg;
if ((arg = (ArgList) malloc(sizeof(struct ArgListStruct)))
== NULL) {
log_message("# CreateArgList() -- out of memory");
log_close();
external_cleanup();
exit(1);
}
/* initialize and allocate the arglist */
arg->size = FILE_LIST_BLOCK_SIZE;
arg->num_files = 0;
arg->num_args = 0;
arg->sorted = sorted_list;
/* allocate the argv list */
if ((arg->argv =
(char **) malloc(arg->size * sizeof(char *))) == NULL) {
log_message("# CreateArgList() -- out of memory");
log_close();
external_cleanup();
exit(1);
}
/* return the pointer */
return arg;
}
/*----------------------------------------------------------------------------
*
* DestroyArgList() will deallocate the memory used by the ArgList variable.
*
---------------------------------------------------------------------------*/
void DestroyArgList(ArgList arglist)
{
/* remove the elements */
while (arglist->num_args) {
arglist->num_args--;
free(arglist->argv[arglist->num_args]);
}
/* remove the argv element */
free(arglist->argv);
/* remove the arglist itself */
free(arglist);
}
/*----------------------------------------------------------------------------
*
* ArgToOutputStream() will output all files in argv to stdout
*
---------------------------------------------------------------------------*/
void ArgToOutputStream(FILE * output_file, ArgList arglist)
{
FILE *input_file; /* file ptr */
char **argv; /* the actual argument list */
int argc; /* the number of elements in arglist */
int c; /* temporary character */
argc = arglist->num_args;
argv = arglist->argv;
while (argc) {
if ((input_file = fopen(*argv, "r")) == (FILE *) NULL) {
log_message("# ArgToOutputStream() -- file open error");
}
else {
c = fgetc(input_file);
while (!feof(input_file)) {
fputc(c, output_file);
c = fgetc(input_file);
}
fclose(input_file);
}
argc--;
argv++;
}
}
/*----------------------------------------------------------------------------
*
* ArgIsMember() returns true if s is a member of the string array arg
*
---------------------------------------------------------------------------*/
BOOLEAN ArgIsMember(ArgList argf, char *arg)
{
int i;
int start, end;
int compare;
if (argf->sorted) {
/* do a binary search */
start = 0;
end = argf->num_args - 1;
while (start <= end) {
/* compute new index and compare to argument */
i = (start + end) / 2;
compare = stricmp(arg, argf->argv[i]);
/* if the element is found return true */
if (!compare)
return TRUE;
/* narrow the search or stop the search if needed */
if (compare < 0) {
/* if the index is already equal to end then the element is
* not present and start is equal to end, move start beyond
* end */
if (end == i)
start++;
end = i;
}
else {
/* if start and end are the same then the element is not
* present */
if (start == i)
i++;
start = i;
}
}
}
else {
/* Do a linear search, loop through until we determine if the arg is
* currently an element of argf */
for (i = 0; (unsigned int) i < argf->num_args; i++) {
if (!stricmp(argf->argv[i], arg)) {
return TRUE;
}
}
}
/* if we reach here, it is not in the arglist */
return FALSE;
}
/*----------------------------------------------------------------------------
*
* ArgCopy() copies all the elements of argfrom to argto while adding
* internal bookkeeping variables
*
---------------------------------------------------------------------------*/
void ArgCopy(ArgList argto, ArgList argfrom)
{
unsigned int i;
/* loop through until we have copied them all */
for (i = 0; i < argfrom->num_args; i++) {
ArgRegisterArg(argto, argfrom->argv[i]);
}
/* add the number of file arguments to the destination */
argfrom->num_files += argto->num_files;
}
/*----------------------------------------------------------------------------
*
* ArgRegisterArg() places an argument in the ArgList array and increments
* arglist->num_args
*
---------------------------------------------------------------------------*/
void ArgRegisterArg(ArgList argf, char *arg)
{
char *arg_string;
int i;
int start, end;
int compare;
int insertion_index;
/* allocate the file name array and copy */
if ((arg_string = malloc(sizeof(char) * (strlen(arg) + 1))) ==
(char *) NULL) {
log_message("# RegisterArg() -- out of memory");
log_close();
external_cleanup();
exit(1);
}
strcpy(arg_string, arg);
/* reallocate the file list array if needed */
if (argf->num_args >= argf->size) {
/* update the arglist size */
argf->size += FILE_LIST_BLOCK_SIZE;
/* reallocate the block */
if ((argf->argv = realloc(argf->argv, argf->size * sizeof(char *))) ==
NULL) {
log_message("# RegisterArg() -- out of memory");
log_close();
external_cleanup();
exit(1);
}
}
if (argf->sorted) {
/* do a binary insertion sort, by first doing the binary search and
* then an insertion */
start = 0;
end = argf->num_args - 1;
i = 0;
compare = -1;
while (start <= end) {
/* compute new index and compare to argument */
i = (start + end) / 2;
compare = stricmp(arg, argf->argv[i]);
/* if the element is already in the list then return */
if (!compare)
return;
/* narrow the search or stop the search if needed */
if (compare < 0) {
/* if the index is already equal to end then the element is
* not present and start is equal to end, move start beyond
* e